package com.zzw.config;

import com.zzw.bean.Permissions;
import com.zzw.bean.Roles;
import com.zzw.bean.SysUser;
import com.zzw.dao.PermissionsMapper;
import com.zzw.service.RolesService;
import com.zzw.service.SysUserService;
import com.zzw.utils.PasswordEncoderUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.shiro.SecurityUtils;

import java.util.Collection;
import java.util.List;

/**
 * 自定义Realm实现
 * 用于处理用户认证和授权
 */
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private RolesService rolesService;

    @Autowired
    private PermissionsMapper permissionsMapper;

    // 超级管理员角色名称
    private static final String SUPER_ADMIN_ROLE = "超级管理员";

    /**
     * 设置缓存名称，与ehcache.xml中的缓存名称对应
     */
    public CustomRealm() {
        // 设置授权缓存的名称，对应ehcache.xml中的缓存名称
        this.setAuthorizationCacheName("authorizationCache");
        // 设置认证缓存的名称
        this.setAuthenticationCacheName("authenticationCache");
        // 开启缓存
        this.setCachingEnabled(true);
        // 开启授权缓存
        this.setAuthorizationCachingEnabled(true);
        // 开启认证缓存
        this.setAuthenticationCachingEnabled(false);
    }

    /**
     * 授权方法
     * 用于获取用户的角色和权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取登录用户名
        SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();
        Integer userId = user.getId();

        // 创建授权信息对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        // 查询用户角色
        List<Roles> roles = rolesService.selectRolesByUserId(userId);

        // 添加角色
        for (Roles role : roles) {
            authorizationInfo.addRole(role.getName());

            // 查询角色权限
            List<Permissions> permissions = permissionsMapper.selectPermissionByRoleId(role.getId());
            for (Permissions permission : permissions) {
                // 添加权限
                authorizationInfo.addStringPermission(permission.getName());
            }
        }

        return authorizationInfo;
    }

    /**
     * 认证方法
     * 用于验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取用户名
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();

        // 查询用户
        SysUser user = sysUserService.findByUsername(username);

        // 用户不存在
        if (user == null) {
            throw new UnknownAccountException("用户不存在");
        }

        // 账号被禁用
        if ("0".equals(user.getStatus())) {
            throw new DisabledAccountException("账号已被禁用");
        }

        // 不再手动验证密码，交给CredentialsMatcher处理
        // 返回认证信息（传入数据库中的加密密码）
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }

    /**
     * 清除认证和授权缓存
     */
    public void clearCache() {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
        this.clearCachedAuthenticationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    /**
     * 重写权限判断方法
     * 超级管理员拥有所有权限
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        // 获取当前用户
        SysUser user = (SysUser) principals.getPrimaryPrincipal();
        // 查询用户角色
        List<Roles> roles = rolesService.selectRolesByUserId(user.getId());

        // 判断是否为超级管理员
        for (Roles role : roles) {
            if (SUPER_ADMIN_ROLE.equals(role.getName())) {
                // 超级管理员拥有所有权限
                return true;
            }
        }

        // 非超级管理员，调用父类方法进行常规权限检查
        return super.isPermitted(principals, permission);
    }

    /**
     * 重写权限判断方法(集合形式)
     * 超级管理员拥有所有权限
     */
    @Override
    public boolean[] isPermitted(PrincipalCollection principals, String... permissions) {
        // 获取当前用户
        SysUser user = (SysUser) principals.getPrimaryPrincipal();
        // 查询用户角色
        List<Roles> roles = rolesService.selectRolesByUserId(user.getId());

        // 判断是否为超级管理员
        for (Roles role : roles) {
            if (SUPER_ADMIN_ROLE.equals(role.getName())) {
                // 超级管理员拥有所有权限
                boolean[] result = new boolean[permissions.length];
                for (int i = 0; i < permissions.length; i++) {
                    result[i] = true;
                }
                return result;
            }
        }

        // 非超级管理员，调用父类方法进行常规权限检查
        return super.isPermitted(principals, permissions);
    }

    /**
     * 重写权限判断方法(Permission对象形式)
     * 超级管理员拥有所有权限
     */
    @Override
    public boolean isPermitted(PrincipalCollection principals, Permission permission) {
        // 获取当前用户
        SysUser user = (SysUser) principals.getPrimaryPrincipal();
        // 查询用户角色
        List<Roles> roles = rolesService.selectRolesByUserId(user.getId());

        // 判断是否为超级管理员
        for (Roles role : roles) {
            if (SUPER_ADMIN_ROLE.equals(role.getName())) {
                // 超级管理员拥有所有权限
                return true;
            }
        }

        // 非超级管理员，调用父类方法进行常规权限检查
        return super.isPermitted(principals, permission);
    }
}
